package cn.hyh.core.config;

import cn.hyh.core.component.MyShiroRealm;
import cn.hyh.core.component.MyUserFilter;
import cn.hyh.core.component.ShiroLoginFilter;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * @auther :hyh
 * @desc :
 * @date :2019/7/11
 */
@Configuration
public class ShiroConfig {



    @Bean
    public Realm  myShiroRealm() {
        return new MyShiroRealm();
    }

    //配置ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();

//          //配置 自定义的 拦截器
//        Map<String, Filter> map = new HashMap<>();
//          filterFactory.setFilters(map);
        filterFactory.setLoginUrl("/login");  // 设置登录界面

        filterFactory.setSecurityManager(DefaultWebSecurityManager());   // 设置核心的安全管理器

        //配置权限控制的map, 这个有顺序，所以必须用linkedHashMap
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();


//          //authc 是shiro 自带的验证 filter   roles 是shiro 自带的 授权的拦截器的filter
//         // 该请求路径要执行的拦截器链是FormAuthenticationFilter，RolesAuthorizationFilter
//        filterChainDefinitionMap.put("/get/**", "authc,roles[admin]");
        filterChainDefinitionMap.put("/user/**", "anon");   //ant风格
        filterChainDefinitionMap.put("/blog/**", "anon");
        filterChainDefinitionMap.put("/dic/**", "anon");
        filterChainDefinitionMap.put("/msg/**", "anon");
        filterChainDefinitionMap.put("/validateLogin", "anon");   //验证是否登录的接口，也可以直接访问。
        filterChainDefinitionMap.put("/login", "anon");   //验证是否登录的接口，也可以直接访问。
        filterChainDefinitionMap.put("/write/writeBlog", "auth,roles[admin]");
        filterFactory.setFilterChainDefinitionMap(filterChainDefinitionMap);
        Map<String, Filter> map = new HashMap<>();
        map.put("auth", new MyUserFilter());
         filterFactory.setFilters(map); //用于添加自定义的过滤器。
        return filterFactory;
    }

    @Bean
    public DefaultWebSecurityManager DefaultWebSecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setSessionManager(sessionManager());
        securityManager.setCacheManager(ehCacheManager());
        return securityManager;
    }

    //使用enchae进行会话的存储  管理如用户、角色、权限等的缓存的
    @Bean
    public EhCacheManager  ehCacheManager() {
        EhCacheManager ehCacheManager = new EhCacheManager();
//           ehCacheManager.setCacheManagerConfigFile("classpath:ehcahe-shiro.xml");
        ehCacheManager.setCacheManager(CacheManager.create());
        return ehCacheManager;
    }


    //配置全局的session 管理器， 由于是web应用，就用websession
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
           sessionManager.setGlobalSessionTimeout(1000*60*60*2); //设置全局的session 4个小时
        sessionManager.setSessionDAO(SessionDAO());
        return sessionManager;
    }

    //设置会话的存储，默认是map中
    @Bean
    public SessionDAO SessionDAO() {
        SessionDAO dao = new MemorySessionDAO();

        return dao;
    }

    //shiro 的生命周期
    @Bean
    public LifecycleBeanPostProcessor  lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

   //自动创建代理     借助springAOP 来 实现shiro注解
   @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
       DefaultAdvisorAutoProxyCreator daapc = new DefaultAdvisorAutoProxyCreator();
       daapc.setProxyTargetClass(true);
       return daapc;
   }

   //开启shiro aop注解
    @Bean
    public AuthorizationAttributeSourceAdvisor  authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor  advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(DefaultWebSecurityManager());
        return advisor;
    }
}
